<?php
/* SVN FILE: $Id: HamlHelpers.php 92 2010-05-20 17:42:59Z chris.l.yates $ */
/**
 * HamlHelpers class file.
 * 
 * @author			Chris Yates <chris.l.yates@gmail.com>
 * @copyright 	Copyright (c) 2010 PBM Web Development
 * @license			http://phamlp.googlecode.com/files/license.txt
 * @package			PHamlP
 * @subpackage	Haml
 */

/**
 * HamlHelpers class.
 * Contains methods to make it easier to do various tasks.
 * 
 * The class can be extended to provide user defined helper methods. The
 * signature for user defined helper methods is ($block, $other, $arguments);
 * $block is the string generated by the Haml block being operated on.
 * 
 * Tthe path to the extended class is provided to HamlParser in the config
 * array; class name == file name.
 * 
 * HamlHelpers and any extended class are automatically included in the context
 * that a Haml template is parsed in, so all the methods are at your disposal
 * from within the template.
 * 
 * @package			PHamlP
 * @subpackage	Haml
 */
class HamlHelpers {
	const XMLNS = 'http://www.w3.org/1999/xhtml';
	
	/**
	 * Returns the block with string appended.
	 * @see succeed
	 * @param string Haml block
	 * @param string string to append
	 * @return string the block with string appended.
	 */
	public static function append($block, $string) {
	  return $block.$string;
	}
	
	/**
	 * Escapes HTML entities in text, but without escaping an ampersand that is
	 * already part of an escaped entity.
	 * @param string Haml block
	 * @return string the block with HTML entities escaped.
	 */
	public static function escape_once($block) {
	  return htmlentities(html_entity_decode($block));
	}
	
	/**
	 * Returns an array containing default assignments for the xmlns, lang, and
	 * xml:lang attributes of the html element.
	 * This helper method is for use in the html element only.
	 * 
	 * Examples:<br/>
	 * %html(html_attrs())<br/> 
	 * produces<br/> 
	 * <html lang="en-us" xml:lang="en-us" xmlns="http://www.w3.org/1999/xhtml">
	 * 
	 * %html(html_attrs('en-gb'))<br/> 
	 * produces<br/>
	 * <html lang="en-gb" xml:lang="en-gb" xmlns="http://www.w3.org/1999/xhtml">
	 * 
	 * %html(html_attrs('en-gb', false))<br/> 
	 * produces<br/> 
	 * <html xml:lang="en-gb" xmlns="http://www.w3.org/1999/xhtml">
	 * 
	 * Although handled in HamlParser, the notes below are here for completeness.<br/> 
	 * Other attributes are defined as normal. e.g.<br/> 
	 * %html(xmlns:me="http://www.example.com/me" html_attrs('en-gb', false))<br/> 
	 * produces<br/> 
	 * <html xml:lang="en-gb" xmlns="http://www.w3.org/1999/xhtml" xmlns:me="http://www.example.com/me">
	 * 
	 * PHamlP also allows for the language to be defined using PHP code that can 
	 * be eval'd; the code must end with a semi-colon (;). e.g.<br/> 
	 * %html(html_attrs("FW::app()->language);", false))<br/> 
	 * produces (assuming FW::app()->language returns 'en-gb')<br/> 
	 * <html xml:lang="en-gb" xmlns="http://www.w3.org/1999/xhtml">
	 * 
	 * @param string document language. Default = en-us
	 * @param boolean whether the html element has the lang attribute. Default: true
	 * Should be set false for XHTML 1.1 or greater documents
	 * @return string the block with string appended.
	 */
	public static function html_attrs($language = 'en-us', $lang = true)  {
	  return ($lang ?
	  	array('xmlns'=>self::XMLNS, 'xml:lang'=>$language, 'lang'=>$language) :
	  	array('xmlns'=>self::XMLNS, 'xml:lang'=>$language));
	}
	
	/**
	 * Returns a copy of text with ampersands, angle brackets and quotes escaped
	 * into HTML entities.
	 * @param string Haml block
	 * @return string the block with HTML entities escaped.
	 */
	public static function html_escape($block) {
	  return htmlspecialchars($block);
	}
	
	/**
	 * Iterates an array and using the block to generate a <li> element for each
	 * array element.
	 * Examples:<br/>
	 * = list_of(array('red', 'orange', ...., 'violet'), 'colour')<br/>
	 * 	= colour<br/>
	 * Produces:<br/>
	 * <li>red</li><br/>
	 * <li>orange</li><br/>
	 *    |<br/>
	 *    |<br/>
	 * <li>violet></li><br/>
	 * 
	 * = list_of(array('Fly Fishing' => 'JR Hartley', 'Lord of the Rings' => 'JRR Tolkien'), 'title', 'author')<br/>
	 *   %h3= title<br/>
	 *   %p= author<br/>
	 * Produces:<br/>
	 * <li><br/>
	 *   <h3>Fly Fishing</h3><br/>
	 *   <p>JR Hartley</p><br/>
	 * </li><br/>
	 * <li><br/>
	 *   <h3>Lord of the Rings</h3><br/>
	 *   <p>JRR Tolkien</p><br/>
	 * </li><br/>
	 * 
	 * @param string Haml block
	 * @param array items
	 * @param string string in block to replace with item key or item value
	 * @param string string in block to replace with item value
	 * @return string list items.
	 */
	public static function list_of($block, $items, $key, $value = null) {
		$output = '';
		foreach ($items as $_key=>$_value) {
			$output .= '<li>' . strtr($block, (empty($value) ? array($key=>$_value) :
					array($key=>$_key, $value=>$_value))) . '</li>';
		} // foreach
		return $output;
	}
	
	/**
	 * Alias for prepend.
	 * @see prepend
	 * @param string Haml block
	 * @param string string to prepend
	 * @return string the block with string prepended
	 */
	public static function preceed($block, $string) {
		return self::prepend($block, $string);
	}
	
	/**
	 * Returns the block with string prepended.
	 * @param string Haml block
	 * @param string string to prepend
	 * @return string the block with string prepended
	 */
	public static function prepend($block, $string) {
		return $string.$block;
	}
	
	/**
	 * Converts newlines in the block to HTML entities.
	 * @param string Haml block
	 * @return string the block with newlines converted to HTML entities
	 */
	public static function preserve($block) {
		return str_replace("\n", '&#x0d;&#x0a;', $block);
	}
	
	/**
	 * Alias for append.
	 * @see append
	 * @param string Haml block
	 * @param string string to apppend
	 * @return string the block with string apppended
	 */
	public static function succeed($block, $string) {
		return self::append($block, $string);
	}
	
	/**
	 * Surrounds a block of Haml code with strings.
	 * If $back is not given it defaults to $front.
	 * @param string Haml block
	 * @param string string to prepend
	 * @param string string to apppend
	 * @return string the block surrounded by the strings
	 */
	public static function surround($block, $front, $back=null) {
	  return $front.$block.(is_null($back) ? $front : $back);
	}	
}